package com.jacobson.core.di.modules

import com.jacobson.core.framework.configuration.GsonConfiguration
import com.jacobson.core.framework.configuration.OkHttpClientConfiguration
import com.jacobson.core.framework.configuration.RetrofitConfiguration
import com.jacobson.core.framework.dialog.DialogHandler
import com.jacobson.core.framework.errorhandler.OnErrorListener
import com.jacobson.core.framework.errorhandler.OnResponseErrorListener
import com.jacobson.core.widget.security.SecurityStorage
import com.jacobson.core.widget.security.SecurityManager
import dagger.Module
import dagger.Provides
import javax.inject.Named
import javax.inject.Singleton

/**
 * ================================================
 * 开发者全局配置实例,外部通过此向框架注入参数
 * @author Wucz on 2018/7/18 15:28
 * ================================================
 */

@Module
class GlobalConfigurationModule internal constructor(builder: Builder) {
    private var retrofitConfiguration: RetrofitConfiguration
    private var okHttpClientConfiguration: OkHttpClientConfiguration
    private var gsonConfiguration: GsonConfiguration
    private var onErrorListener: OnErrorListener
    private var dialogHandlerFactory: () -> DialogHandler
    private var densitySupport: Boolean = true

    init {
        builder.let {
            retrofitConfiguration = it.retrofitConfiguration!!
            okHttpClientConfiguration = it.okHttpClientConfiguration!!
            gsonConfiguration = it.gsonConfiguration!!
            onErrorListener = it.onErrorListener!!
            densitySupport = it.densitySupport
            dialogHandlerFactory = it.dialogHandlerFactory!!
            SecurityStorage.init(it.securityManager!!)
        }
    }

    /**
     * 是否支持屏幕适配
     */
    @Singleton
    @Provides
    @Named("densitySupport")
    fun provideDensitySupport(): String {
        return densitySupport.toString()
    }

    /**
     * 提供Retrofit配置信息
     */
    @Singleton
    @Provides
    fun provideRetrofitConfiguration(): RetrofitConfiguration {
        return retrofitConfiguration
    }

    /**
     * 提供OkHttpClientConfiguration的配置信息
     */
    @Singleton
    @Provides
    fun provideOkHttpClientConfiguration(): OkHttpClientConfiguration {
        return okHttpClientConfiguration
    }

    /**
     * 提供GsonConfiguration的配置信息
     */
    @Singleton
    @Provides
    fun provideGsonConfiguration(): GsonConfiguration {
        return gsonConfiguration
    }

    @Singleton
    @Provides
    fun provideOnErrorListener(): OnErrorListener {
        return onErrorListener
    }

    @Provides
    fun provideGlobalDialogHandler(): DialogHandler {
        return dialogHandlerFactory.invoke()
    }

    class Builder internal constructor() {
        internal var retrofitConfiguration: RetrofitConfiguration? = null
        internal var okHttpClientConfiguration: OkHttpClientConfiguration? = null
        internal var gsonConfiguration: GsonConfiguration? = null
        internal var onErrorListener: OnErrorListener? = null
        internal var densitySupport: Boolean = true
        internal var securityManager: SecurityManager? = null
        internal var dialogHandlerFactory: (() -> DialogHandler)? = null

        fun retrofitConfiguration(closure: () -> RetrofitConfiguration): Builder {
            this.retrofitConfiguration = closure()
            return this
        }

        fun okHttpClientConfiguration(closure: () -> OkHttpClientConfiguration): Builder {
            this.okHttpClientConfiguration = closure()
            return this
        }

        fun gsonConfiguration(closure: () -> GsonConfiguration): Builder {
            this.gsonConfiguration = closure()
            return this
        }

        fun densitySupport(closure: () -> Boolean): Builder {
            this.densitySupport = closure()
            return this
        }

        fun securityManager(closure: () -> SecurityManager): Builder {
            this.securityManager = closure()
            return this
        }

        fun onErrorListener(closure: () -> OnErrorListener): Builder {
            this.onErrorListener = closure()
            return this
        }

        fun dialogHandler(closure: () -> DialogHandler): Builder {
            this.dialogHandlerFactory = closure
            return this
        }

        internal fun build(): GlobalConfigurationModule {
            onErrorListener = onErrorListener ?: OnResponseErrorListener.EMPTY
            gsonConfiguration = gsonConfiguration ?: GsonConfiguration.build {}
            okHttpClientConfiguration = okHttpClientConfiguration ?: OkHttpClientConfiguration.build {}
            retrofitConfiguration = retrofitConfiguration ?: RetrofitConfiguration.build {}
            dialogHandlerFactory = dialogHandlerFactory ?: { DialogHandler.DefaultDialogHandler() }
            return GlobalConfigurationModule(this)
        }
    }

    companion object {
        fun newBuilder(): Builder = Builder()

    }
}